﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

/// <summary>
/// 日志捕获服务类
/// </summary>
public class LogcatCaptureService : IDisposable
{
    private ProcessStartInfo _startInfo;
    private BackgroundWorker _pingWorker;
    private CancellationTokenSource _cancellationTokenSource;
    private List<LogcatModel> _logcatModels;
    private string _commandLog;
    private string _adbPath;
    public bool _isDebugMode;
    private Process _logcatProcess;

    public event Action<LogcatModel> OnLogReceived;
    public event Action<string> OnError;
    public event Action<string> OnStatusChanged;

    // 添加一个标志来防止递归
    private bool _isProcessingLogcatOutput = false;
    private bool _isProcessingCommandOutput = false;

    public LogcatCaptureService(string adbPath, string commandLog, bool debugMode = false)
    {
        _adbPath = adbPath;
        _commandLog = commandLog;
        _isDebugMode = debugMode;
        _logcatModels = new List<LogcatModel>();

        InitializeProcessStartInfo();
        InitializeBackgroundWorker();
    }

    private void InitializeProcessStartInfo()
    {
        _startInfo = new ProcessStartInfo
        {
            FileName = "cmd.exe",
            Arguments = $"/c {_commandLog}",
            WorkingDirectory = _adbPath
        };

        // 在调试模式下显示窗口，非调试模式下重定向输出
        if (_isDebugMode)
        {
            Console.WriteLine($"[DEBUG] 调试模式：显示CMD窗口");
            _startInfo.UseShellExecute = true;
            _startInfo.CreateNoWindow = false;
            _startInfo.WindowStyle = ProcessWindowStyle.Normal;
        }
        else
        {
            Console.WriteLine($"[DEBUG] 生产模式：重定向输出");
            _startInfo.RedirectStandardOutput = true;
            _startInfo.RedirectStandardError = true;
            _startInfo.UseShellExecute = false;
            _startInfo.CreateNoWindow = true;
        }
    }

    private void InitializeBackgroundWorker()
    {
        _pingWorker = new BackgroundWorker
        {
            WorkerSupportsCancellation = true
        };
        _pingWorker.DoWork += PingWorker_DoWork;
        _pingWorker.RunWorkerCompleted += PingWorker_RunWorkerCompleted;
    }

    /// <summary>
    /// 开始日志捕获
    /// </summary>
    public bool StartCapture()
    {
        try
        {
            if (_pingWorker.IsBusy)
            {
                Console.WriteLine($"[WARNING] 日志捕获已经在运行中");
                OnStatusChanged?.Invoke("日志捕获已经在运行中");
                return false;
            }

            _cancellationTokenSource = new CancellationTokenSource();
            _pingWorker.RunWorkerAsync(_cancellationTokenSource.Token);

            Console.WriteLine($"[INFO] 开始日志捕获");
            OnStatusChanged?.Invoke("开始日志捕获");
            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[ERROR] 启动日志捕获失败: {ex.Message}");
            OnError?.Invoke($"启动日志捕获失败: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 停止日志捕获
    /// </summary>
    public bool StopCapture()
    {
        bool success = true;

        try
        {
            Console.WriteLine($"[INFO] 停止日志捕获请求已发送");
            OnStatusChanged?.Invoke("停止日志捕获请求已发送");

            // 取消后台工作
            _cancellationTokenSource?.Cancel();

            if (_pingWorker.IsBusy)
            {
                _pingWorker.CancelAsync();
            }

            // 杀死日志捕获进程
            CleanupProcess();

            // 等待工作器停止
            int waitCount = 0;
            while (_pingWorker.IsBusy && waitCount < 50) // 最多等待5秒
            {
                Thread.Sleep(100);
                waitCount++;
            }

            if (_pingWorker.IsBusy)
            {
                Console.WriteLine($"[WARNING] 日志捕获线程未能正常停止");
                success = false;
            }
            else
            {
                Console.WriteLine($"[INFO] 日志捕获已停止");
            }

            return success;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[ERROR] 停止日志捕获时出错: {ex.Message}");
            OnError?.Invoke($"停止日志捕获时出错: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 重启日志捕获
    /// </summary>
    public void RestartCapture()
    {
        Console.WriteLine($"[INFO] 重启日志捕获");
        StopCapture();
        Thread.Sleep(1000);
        StartCapture();
    }

    private void PingWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        var worker = sender as BackgroundWorker;
        var token = (CancellationToken)e.Argument;

        try
        {
            Console.WriteLine($"[INFO] 启动日志进程...");
            OnStatusChanged?.Invoke("启动日志进程...");

            _logcatProcess = Process.Start(_startInfo);

            if (_logcatProcess == null)
            {
                Console.WriteLine($"[ERROR] 无法启动日志进程");
                OnError?.Invoke("无法启动日志进程");
                return;
            }

            Console.WriteLine($"[INFO] 日志进程已启动，开始捕获...");
            OnStatusChanged?.Invoke("日志进程已启动，开始捕获...");

            // 调试模式下不处理输出，直接等待
            if (_isDebugMode)
            {
                Console.WriteLine($"[INFO] 调试模式：CMD窗口已显示，等待用户操作...");
                OnStatusChanged?.Invoke("调试模式：CMD窗口已显示，等待用户操作...");
              
                // 在调试模式下，等待进程结束或取消请求
                while (!token.IsCancellationRequested && !_logcatProcess.HasExited)
                {
                    Thread.Sleep(100);
                }
            }
            else
            {
                // 非调试模式：处理输出流
                ProcessOutputStream(token);
            }

            // 清理进程
            CleanupProcess();
            Console.WriteLine($"[INFO] 日志捕获工作线程已退出");
            OnStatusChanged?.Invoke("日志捕获工作线程已退出");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[ERROR] 日志捕获出错: {ex.Message}");
            Console.WriteLine($"[ERROR] 堆栈跟踪: {ex.StackTrace}");
            OnError?.Invoke($"日志捕获出错: {ex.Message}");

            CleanupProcess();
        }
    }

    private void ProcessOutputStream(CancellationToken token)
    {
        while (!token.IsCancellationRequested && !_logcatProcess.HasExited)
        {
            string output = _logcatProcess.StandardOutput.ReadLine();
            if (string.IsNullOrEmpty(output))
            {
                Thread.Sleep(10);
                continue;
            }

            // 输出原始日志用于调试
            Console.WriteLine($"[RAW] {output}");

            if (ParseRegisterLog(output, out string regAddr, out string value, out bool isRead, out string module))
            {
                var logModel = new LogcatModel()
                {
                    Date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
                    RWText = module,
                    RegAddr = regAddr,
                    Values = value,
                    Operation = isRead ? "读" : "写"
                };

                lock (_logcatModels)
                {
                    _logcatModels.Add(logModel);

                    // 限制日志数量，避免内存溢出
                    if (_logcatModels.Count > 1000)
                    {
                        _logcatModels.RemoveAt(0);
                    }
                }

                // 触发事件
                OnLogReceived?.Invoke(logModel);

                // 输出解析成功的日志
                Console.WriteLine($"[PARSED] {logModel.RWText} - {logModel.RegAddr} - {logModel.Values} - {logModel.Operation}");
            }
        }
    }

    private void CleanupProcess()
    {
        try
        {
            if (_logcatProcess != null && !_logcatProcess.HasExited)
            {
                Console.WriteLine($"[INFO] 清理日志进程...");
                _logcatProcess.Kill();
                Thread.Sleep(100); // 给进程一点时间退出
                _logcatProcess.Dispose();
                _logcatProcess = null;
                Console.WriteLine($"[INFO] 日志进程已清理");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[ERROR] 清理进程时出错: {ex.Message}");
        }
    }

    private void PingWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            Console.WriteLine($"[ERROR] 工作线程异常: {e.Error.Message}");
            OnError?.Invoke($"工作线程异常: {e.Error.Message}");
        }

        Console.WriteLine($"[INFO] 日志捕获已停止");
        OnStatusChanged?.Invoke("日志捕获已停止");
    }

    /// <summary>
    /// 从日志行中解析寄存器信息
    /// </summary>
    private bool ParseRegisterLog(string logLine, out string regAddr, out string value, out bool isRead, out string module)
    {
        regAddr = null;
        value = null;
        isRead = false;
        module = null;

        if (string.IsNullOrEmpty(logLine))
            return false;

        // 匹配 SensorRead/SensorWrite 格式: "SensorRead addr=0x100 val=0x1 id=34"
        Match match = Regex.Match(logLine, @"(ISP|Sensor|Reg)(Read|Write)\s+addr=(0x[0-9a-fA-F]+)\s+val=(0x[0-9a-fA-F]+)\s+id=([0-9]+)");

        if (!match.Success)
            return false;

        try
        {
            module = match.Groups[1].Value; // ISP 或 Sensor 或 Reg
            string operation = match.Groups[2].Value; // Read 或 Write
            regAddr = match.Groups[3].Value; // 地址
            value = match.Groups[4].Value; // 值
            isRead = operation.ToLower() == "read";

            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[ERROR] 解析日志失败: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 获取日志数据
    /// </summary>
    public List<LogcatModel> GetLogs()
    {
        lock (_logcatModels)
        {
            return new List<LogcatModel>(_logcatModels);
        }
    }

    /// <summary>
    /// 获取最新的日志数据（指定数量）
    /// </summary>
    public List<LogcatModel> GetRecentLogs(int count)
    {
        lock (_logcatModels)
        {
            if (_logcatModels.Count <= count)
                return new List<LogcatModel>(_logcatModels);

            return _logcatModels.GetRange(_logcatModels.Count - count, count);
        }
    }

    /// <summary>
    /// 清空日志数据
    /// </summary>
    public void ClearLogs()
    {
        lock (_logcatModels)
        {
            _logcatModels.Clear();
            Console.WriteLine($"[INFO] 日志数据已清空");
        }
    }

    /// <summary>
    /// 检查日志捕获状态
    /// </summary>
    public bool IsRunning
    {
        get { return _pingWorker.IsBusy; }
    }

    public void Dispose()
    {
        StopCapture();
        _pingWorker?.Dispose();
        _cancellationTokenSource?.Dispose();
        _logcatProcess?.Dispose();
    }
}

